<?php
require_once 'Structures/DataGrid/DataSource.php';
require_once 'Pager/Pager.php';
require_once 'lib/generic_data.class.php';

class generic_data_pager extends Structures_DataGrid_DataSource {
 
    /* Interface to generic_data class - abstract data accessor */
    private $generic_data_mdb   =   false;
    private $dsn                =   false;
    private $table              =   false;
    private $database           =   false;
    private $primary_key        =   false;
     public $pager_options      =   array();
     public $pager              =   false;  // DB::Page object
     public $result_data_attributes =   array();
     public $result_data            =   array();
     
    function __construct($options = array()) {
        foreach($options as $attribute => $value) {
            if(isset($this->$attribute)) {
                $this->$attribute    =   $value;
            }
        }
        
        // parent class attributes - when not set, throws notices for some reason
        // Since it's a PEAR class throwing these, I'm not fixing it.
        $this->_options['generate_columns'] =   '';
        $this->_options['fields']           =   '';
        
        // this seems like it could be a good feature.  Will have to research
        // the capabilities of the queryTools / MDB strategy I have taken to see
        // if it's possible to provide this feature.
        $this->_features['multiSort']       =   '';
        
        try {
            $this->set_generic_data_mdb();
            $this->set_pager();
        } catch(Exception $e) {
            echo "Could not init generic_data_pager".$e->getMessage();;
        }
        
    }
    
    public function get_initial_page_index_from_extjs() {
        if(isset($_REQUEST['start']) && isset($_REQUEST['limit'])) {
            return ($_REQUEST['start'] / $_REQUEST['limit']) + 1;
        }
        return false;
    }
    
    private function set_generic_data_mdb() {
        $generic_data_options       =   array(  'dsn'   =>  $this->dsn,
                                                'table' =>  $this->table,                                             
                                                'primaryCol'    =>  $this->primary_key
                                                );
        $this->generic_data_mdb     =   new generic_data($generic_data_options);
        
        $this->generic_data_mdb->set_querytool_attributes($this->table, $this->primary_key);
    }
    
    /** set_pager
    *
    *   Pager options (got tired of looking these damn things up.. I miss dual display)
    *
    *  * itemData [array] - Array of items to page.
    *  * totalItems [integer] - Number of items to page (used only if itemData is not provided).
    *    perPage [integer] - Number of items to display on each page.
    *    delta [integer] - Number of page numbers to display before and after the current one.
    *    mode [string] - "Jumping" or "Sliding" -window - It determines pager behaviour.
    *    httpMethod [string] - Specifies the HTTP method to use. Valid values are 'GET' or 'POST'.
    *    formID [string] - Specifies which HTML form to use in POST mode.
    *    importQuery [boolean] - if true (default behaviour), variables and values are imported from the submitted data (query string) and used in the generated links, otherwise they're ignored completely
    *    currentPage [integer] - Initial page number (if you want to show page #2 by default, set currentPage to 2)
    *    expanded [boolean] - if TRUE, window size is always 2*delta+1
    *    linkClass [string] - Name of CSS class used for link styling.
    *    urlVar [string] - Name of URL var used to indicate the page number. Default value is "pageID".
    *    path [string] - Complete path to the page (without the page name).
    *    fileName [string] - name of the page, with a "%d" if append == TRUE.
    *    fixFileName [boolean] - If set to FALSE, the fileName option is not overridden. Use at your own risk.
    *    append [boolean] - If TRUE pageID is appended as GET value to the URL. If FALSE it is embedded in the URL according to fileName specs.
    *    altFirst [string] - Alt text to display on the link of the first page. Default value is "first page"; if you want a string with the page number, use "%d" as a placeholder (for instance "page %d")
    *    altPrev [string] - Alt text to display on the link of the previous page. Default value is "previous page";
    *    altNext [string] - Alt text to display on the link of the next page. Default value is "next page";
    *    altLast [string] - Alt text to display on the link of the last page. Default value is "last page"; if you want a string with the page number, use "%d" as a placeholder (for instance "page %d")
    *    altPage [string] - Alt text to display before the page number. Default value is "page " (followed by the page number). You can optionally use "%d" as a placeholder (for instance "page n. %d") to place the page number where you want.
    *    prevImg [string] - Something to display instead of "<<". It can be text such as "<< PREV" or an <img/> as well.
    *    nextImg [string] - Something to display instead of ">>". It can be text such as "NEXT >>" or an <img/> as well.
    *    separator [string] - What to use to separate numbers. It can be an <img/>, a comma, an hyphen, or whatever.
    *    spacesBeforeSeparator [integer] - Number of spaces before the separator.
    *    spacesAfterSeparator [integer] - Number of spaces after the separator.
    *    firstLinkTitle [string] - String used as title in <link rel="first"> tag
    *    nextLinkTitle [string] - String used as title in <link rel="next"> tag
    *    prevLinkTitle [string] - String used as title in <link rel="previous"> tag
    *    lastLinkTitle [string] - String used as title in <link rel="last"> tag
    *    curPageLinkClassName [string] - CSS class name for the current page link.
    *    curPageSpanPre [string] - Text before the current page link.
    *    curPageSpanPost [string] - Text after the current page link.
    *    firstPagePre [string] - String used before the first page number. It can be an <img/>, a "{", an empty string, or whatever.
    *    firstPageText [string] - String used in place of the first page number.
    *    firstPagePost [string] - String used after the first page number. It can be an <img/>, a "}", an empty string, or whatever.
    *    lastPagePre [string] - Similar to firstPagePre, but used for last page number.
    *    lastPageText [string] - Similar to firstPageText, but used for last page number.
    *    lastPagePost [string] - Similar to firstPagePost, but used for last page number.
    *    clearIfVoid [boolean] - if there's only one page, don't display pager links (returns an empty string).
    *    extraVars [array] - additional URL vars to be added to the querystring.
    *    excludeVars [array] - URL vars to be excluded from the querystring.
    *    useSessions [boolean] - if TRUE, number of items to display per page is stored in the $_SESSION[$_sessionVar] var.
    *    closeSession [boolean] - if TRUE, the session is closed just after R/W.
    *    sessionVar [string] - Name of the session var for perPage value. A value different from default can be useful when using more than one Pager istance in the page.
    *    showAllText [string] - Text to be used for the 'show all' option in the select box generated by getPerPageSelectBox()
    *    pearErrorMode [constant] - PEAR_ERROR mode for raiseError(). Default is PEAR_ERROR_RETURN. 
    *
    */
    function set_pager() {
        $this->pager =& Pager::factory($this->pager_options);
    }

    function count() {
        return $this->generic_data_mdb->getCount();
    }

    /** sort()
    *   
    *   Maps to MDB_Queytool::setOrder
    *
    *   Order params:
    *
    *       null  - no order
    *       true  - ASC
    *       false - DESC
    *   
    *   @access public
    *   @param str, mixed / bool
    *   @return none
    */
    function sort($attribute, $order = null) {
        if(!is_null($order)) {
            $order  =   ($order == 'ASC') ? true : false;
        }
        $this->generic_data_mdb->setOrder($attribute, $order);
    }

    /** fetch()
    *
    *   Fetch by offset
    *
    *   @access public
    *   @param int, int
    *   @return array
    */
    function fetch($offset = 0, $len = null) {
        return $this->generic_data_mdb->getAll($offset, $len);
    }
    
    function set_result_data_attributes($columns = array()) {
        $this->result_data_attributes   =   $columns;
    }
    
    function set_result_data($result_data = array()) {
        $this->result_data  =   $result_data;
    }
    
    /** get result_data_attributes
    *
    *   Array / obj index
    *   -----------------------------
    *
    *   ["id"]=> string(14) "_48dd6b953556a"
    *   ["columnName"]=> string(21) "generic_container_uid"
    *   ["fieldName"]=> string(21) "generic_container_uid"
    *   ["orderBy"]=> string(21) "generic_container_uid"
    *   ["defaultDirection"]=> string(3) "ASC"
    *   ["attribs"]=> array(0) {}
    *   ["autoFillValue"]=> NULL
    *   ["formatter"]=> NULL
    *   ["formatterArgs"]=> NULL
    *   
    */
    function get_result_data_attributes() {
        
        $attributes =   array();
        
        foreach($this->result_data_attributes as $header) {
            
            $attributes[]    =   array(  'name'      =>  $header->fieldName,
                                        'header'    =>  $header->columnName,
                                        'id'        =>  $header->id
                                        );
        }
        
        return $attributes;
    }
    
    function get_result_data() {
        /* in case we have to do some processing in the future.. 
        
        $rows   =   array();
        
        foreach($this->result_data as $key => $value) {
            $rows[] =   array($key  =>  $value);
        } 
        */
        
        return $this->result_data;
    }
    
    function build_extstore_json() {
        
        $fields =   $this->get_result_data_attributes();
        $rows   =   $this->get_result_data();
        
        $results    =   array(  
                        'totalCount' => $this->pager->numItems(),
                        'metaData'  =>  array(  'root'  => 'rows', 
                                                'id'    => 'col1', 
                                                'totalProperty' => 'totalCount', 
                                                'fields'=> $fields,
                                                'columns'=>$fields,
                                               
                                                ),
                        'rows'      =>  $rows,
                        
                      );
        //var_dump($this->pager->Pager::getOffsetByPageId());
        return json_encode($results);
    }
    
}


